package com.newly.common.core.utils;

import cn.hutool.core.util.ObjectUtil;
import com.newly.common.base.constants.CodeConstant;
import com.newly.common.base.entity.auth.CurrentTenantDetails;
import com.newly.common.base.entity.auth.ICurrentTenant;
import com.newly.common.base.entity.auth.TenantDetails;
import com.newly.common.base.exception.NewlyLoginException;
import com.newly.transfer.redis.RedisTransfer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @program: newly-parent
 * @remark: 当前请求信息
 * @author: guan
 * @create: 2021-12-20 23:56
 */
@Component
public class RequestUtils {

    @Autowired
    private RedisTransfer redisTransfer;

    /**
     * 获取当前租户
     *
     * @return CurrentTenantDetails.class
     */
    public ICurrentTenant getCurrentTenant() {
        TenantDetails tenantDetails = redisTransfer.getTenantDetails(resolveTokenUsername());
        if (ObjectUtil.isEmpty(tenantDetails)) {
            throw new NewlyLoginException(CodeConstant.LOGIN_QUIT, "Login timeout!");
        }
        return new CurrentTenantDetails(tenantDetails);
    }

    /**
     * 从request域中获取数据
     *
     * @param key key
     * @return value
     */
    public Object getRequestAttribute(String key) {
        return getAttribute(key, RequestAttributes.SCOPE_REQUEST);
    }

    /**
     * 从请求头中获取数据
     *
     * @param key key
     * @return value
     */
    public Object getHeader(String key) {
        return getRequest().getHeader(key);
    }

    /**
     * 从session域中获取数据
     *
     * @param key key
     * @return value
     */
    public Object getSessionAttribute(String key) {
        return getAttribute(key, RequestAttributes.SCOPE_SESSION);
    }

    /**
     * 从指定域中获取数据
     *
     * @param key   key
     * @param scope 域
     * @return value
     */
    public Object getAttribute(String key, int scope) {
        return RequestContextHolder.getRequestAttributes().getAttribute(key, scope);
    }

    /**
     * 解析token获取用户名
     *
     * @return 用户名
     */
    public String resolveTokenUsername() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (ObjectUtil.isEmpty(authentication)) return null;
        return (String) authentication.getPrincipal();
    }

    /**
     * 获取当前request对象
     *
     * @return HttpServletRequest.class
     */
    public HttpServletRequest getRequest() {
        ServletRequestAttributes requestAttributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return requestAttributes.getRequest();
    }

    /**
     * @return 获取请求ip
     */
    public String getIp() {
        HttpServletRequest request = getRequest();
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 获取浏览器信息
     *
     * @return 浏览器字符串数据
     */
    public String getBrowse() {
        Object header = getHeader("User-Agent");
        if (ObjectUtil.isEmpty(header)) return "";

        String userAgent = (String) header;
        String user = userAgent.toLowerCase();
        String browser = "";
        if (user.contains("edge")) {
            browser = (userAgent.substring(userAgent.indexOf("Edge")).split(" ")[0]).replace("/", "-");
        } else if (user.contains("msie")) {
            String substring = userAgent.substring(userAgent.indexOf("MSIE")).split(";")[0];
            browser = substring.split(" ")[0].replace("MSIE", "IE") + "-" + substring.split(" ")[1];
        } else if (user.contains("safari") && user.contains("version")) {
            browser = (userAgent.substring(userAgent.indexOf("Safari")).split(" ")[0]).split("/")[0]
                    + "-" + (userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1];
        } else if (user.contains("opr") || user.contains("opera")) {
            if (user.contains("opera")) {
                browser = (userAgent.substring(userAgent.indexOf("Opera")).split(" ")[0]).split("/")[0]
                        + "-" + (userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1];
            } else if (user.contains("opr")) {
                browser = ((userAgent.substring(userAgent.indexOf("OPR")).split(" ")[0]).replace("/", "-"))
                        .replace("OPR", "Opera");
            }

        } else if (user.contains("chrome")) {
            browser = (userAgent.substring(userAgent.indexOf("Chrome")).split(" ")[0]).replace("/", "-");
        } else if ((user.indexOf("mozilla/7.0") > -1) || (user.indexOf("netscape6") != -1) ||
                (user.indexOf("mozilla/4.7") != -1) || (user.indexOf("mozilla/4.78") != -1) ||
                (user.indexOf("mozilla/4.08") != -1) || (user.indexOf("mozilla/3") != -1)) {
            browser = "Netscape-?";

        } else if (user.contains("firefox")) {
            browser = (userAgent.substring(userAgent.indexOf("Firefox")).split(" ")[0]).replace("/", "-");
        } else if (user.contains("rv")) {
            String IEVersion = (userAgent.substring(userAgent.indexOf("rv")).split(" ")[0]).replace("rv:", "-");
            browser = "IE" + IEVersion.substring(0, IEVersion.length() - 1);
        } else {
            browser = "UnKnown, More-Info: " + userAgent;
        }
        return browser;
    }

    /**
     * 获取操作系统信息
     *
     * @return 操作系统字符串数据
     */
    public String getOperationSystem() {
        Object header = getHeader("User-Agent");
        if (ObjectUtil.isEmpty(header)) return "";

        String userAgent = (String) header;
        String user = userAgent.toLowerCase();
        String os = "";
        //=================OS Info=======================
        if (userAgent.toLowerCase().indexOf("windows") >= 0) {
            os = "Windows";
        } else if (userAgent.toLowerCase().indexOf("mac") >= 0) {
            os = "Mac";
        } else if (userAgent.toLowerCase().indexOf("x11") >= 0) {
            os = "Unix";
        } else if (userAgent.toLowerCase().indexOf("android") >= 0) {
            os = "Android";
        } else if (userAgent.toLowerCase().indexOf("iphone") >= 0) {
            os = "IPhone";
        } else {
            os = "UnKnown, More-Info: " + userAgent;
        }
        return os;
    }

    /**
     * @return 获取当前请求地址
     */
    public String getReqUrl() {
        HttpServletRequest request = getRequest();
        return request.getRequestURL().toString();
    }
    /**
     * @return 获取当前请求地址
     */
    public String getReqUri() {
        return getRequest().getRequestURI();
    }

    /**
     * @return 获取当前请求方法
     */
    public String getReqMethod() {
        return getRequest().getMethod();
    }
}
